import 'package:dio/dio.dart';

/// 网络请求单例类
class XTXRequestManager {
  //声明Dio
  Dio? _dio;

  // 1.私有的静态属性
  static XTXRequestManager? _instance;

  // 2.私有的命名构造方法
  // 需要在这个构造函数里面创建Dio实例(因为Dio在这个私有的构造函数创建一次)
  XTXRequestManager._initManager() {
    // 创建Dio实例
    if (_dio == null) {
      // 使用BaseOptions设置全局配置信息
      BaseOptions baseoptions = BaseOptions(
        baseUrl: "https://pcapi-xiaotuxian-front.itheima.net/",
        connectTimeout: 15000, //连接超时时间
        receiveTimeout: 5000, //响应超时
      );
      _dio = Dio(baseoptions);

      // 使用dio插件的拦截器
      _dio!.interceptors.add(
        InterceptorsWrapper(
          onRequest: (
            RequestOptions options,
            RequestInterceptorHandler handler,
          ) {
            // 发送请求前的拦截操作
            // 如果需要在发送请求前补充一些额外的逻辑，代码写这里
            // 设置全局的请求头信息：用户的身份信息、客户端类型等
            options.headers = {
              'Authorization': '', //用户身份信息(只有注册登录才有，如果当前没有可以指定'')
              // 客户端类型
              'source-client': 'app',
            };

            return handler.next(options);
          },
          onResponse: (Response response, ResponseInterceptorHandler handler) {
            // 接收响应数据前的拦截操作
            // 如果需要在接收到响应数据后做点什么，代码写这里 （过滤出需要\提取数据）
            return handler.next(response);
          },
          onError: (DioError e, ErrorInterceptorHandler handler) {
            // 捕获到响应错误处理
            // 如果需要在发生错误时做点什么，可以抛出异常或者返回一个 Response 对象
            // (统一的异常处理\用户信息实效了过期了，后端会返回状态码401，如果拦截到401，可以统一的处理401的逻辑)
            return handler.next(e);
          },
        ),
      );
    }
  }

  // 3.创建单例对象并向外界提供获取单例对象的方法（工厂构造函数）
  factory XTXRequestManager() {
    //  判断单例对象是否存在，如果不存在，新建单例对象，反之，直接返回单例对象
    if (_instance == null) {
      _instance = XTXRequestManager._initManager();
    }
    return _instance!;
  }

  /// 处理请求的公共方法
  Future<Response> handleRequest(
    String path,
    String method, {
    data,
    Map<String, dynamic>? queryParameters,
  }) {
    return _dio!.request(
      path,
      data: data,
      queryParameters: queryParameters,
      options: Options(method: method),
    );
  }
}
